﻿namespace KeRui.Common
{
    using System;
    using System.Runtime.CompilerServices;
    using System.Web;
    using System.Web.Caching;

    public class DefaultCacheStrategy : ICacheStrategy
    {
        protected int _timeOut = 0x1770;
        private static readonly DefaultCacheStrategy instance = new DefaultCacheStrategy();
        private static object syncObj = new object();
        protected static volatile Cache webCache = null;

        static DefaultCacheStrategy()
        {
            lock (syncObj)
            {
                HttpContext current = HttpContext.Current;
                if (current != null)
                {
                    webCache = current.Cache;
                }
                else
                {
                    webCache = HttpRuntime.Cache;
                }
            }
        }

        public void AddObject(string objId, object o)
        {
            if (((objId != null) && (objId.Length != 0)) && (o != null))
            {
                CacheItemRemovedCallback onRemoveCallback = null;
                if (this.TimeOut == 60)
                {
                    webCache.Insert(objId, o, null, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.High, onRemoveCallback);
                }
                else
                {
                    webCache.Insert(objId, o, null, DateTime.Now.AddMinutes((double) this.TimeOut), TimeSpan.Zero, CacheItemPriority.High, onRemoveCallback);
                }
            }
        }

        public void AddObjectWith(string objId, object o)
        {
            if (((objId != null) && (objId.Length != 0)) && (o != null))
            {
                CacheItemRemovedCallback onRemoveCallback = null;
                webCache.Insert(objId, o, null, DateTime.Now.AddHours((double) this.TimeOut), Cache.NoSlidingExpiration, CacheItemPriority.High, onRemoveCallback);
            }
        }

        public void AddObjectWithDepend(string objId, object o, string[] dependKey)
        {
            if (((objId != null) && (objId.Length != 0)) && (o != null))
            {
                CacheItemRemovedCallback onRemoveCallback = null;
                CacheDependency dependencies = new CacheDependency(null, dependKey, DateTime.Now);
                webCache.Insert(objId, o, dependencies, DateTime.Now.AddMinutes((double) this.TimeOut), Cache.NoSlidingExpiration, CacheItemPriority.High, onRemoveCallback);
            }
        }

        public void AddObjectWithFileChange(string objId, object o, string[] files)
        {
            if (((objId != null) && (objId.Length != 0)) && (o != null))
            {
                CacheItemRemovedCallback onRemoveCallback = null;
                CacheDependency dependencies = new CacheDependency(files, DateTime.Now);
                webCache.Insert(objId, o, dependencies, DateTime.Now.AddHours((double) this.TimeOut), Cache.NoSlidingExpiration, CacheItemPriority.High, onRemoveCallback);
            }
        }

        public void onRemove(string key, object val, CacheItemRemovedReason reason)
        {
            try
            {
                CacheItemRemovedCallback callback;
                switch (reason)
                {
                    case CacheItemRemovedReason.Removed:
                        callback = new CacheItemRemovedCallback(this.onRemove);
                        webCache.Insert(key, val, null, DateTime.Now.AddMinutes((double) this.TimeOut), Cache.NoSlidingExpiration, CacheItemPriority.High, callback);
                        return;

                    case CacheItemRemovedReason.Expired:
                        callback = new CacheItemRemovedCallback(this.onRemove);
                        webCache.Remove(key);
                        webCache.Insert(key, val, null, DateTime.Now.AddMinutes((double) this.TimeOut), Cache.NoSlidingExpiration, CacheItemPriority.High, callback);
                        return;

                    case CacheItemRemovedReason.Underused:
                        callback = new CacheItemRemovedCallback(this.onRemove);
                        webCache.Insert(key, val, null, DateTime.Now.AddMinutes((double) this.TimeOut), Cache.NoSlidingExpiration, CacheItemPriority.High, callback);
                        return;

                    case CacheItemRemovedReason.DependencyChanged:
                        return;
                }
            }
            catch
            {
            }
        }

        public void RemoveObject(string objId)
        {
            if ((objId != null) && (objId.Length != 0))
            {
                webCache.Remove(objId);
            }
        }

        public object RetrieveObject(string objId)
        {
            if ((objId == null) || (objId.Length == 0))
            {
                return null;
            }
            return webCache.Get(objId);
        }

        public static Cache GetWebCacheObj
        {
            get
            {
                return webCache;
            }
        }

        public int TimeOut
        {
            get
            {
                return ((this._timeOut > 0) ? this._timeOut : 0x1770);
            }
            set
            {
                this._timeOut = (value > 0) ? value : 0x1770;
            }
        }
    }
}

